package yxy.game.pm2.module.arena;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import yxy.apple.logger.Logger;
import yxy.apple.util.concurrent.ThreadPoolManager;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.arenarankreward;
import yxy.cherry.data.bean.arenasignreward;
import yxy.cherry.data.script.fomula;
import yxy.cherry.data.string.GameString;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.module.AreaModule;
import yxy.game.pm2.bean.module.rank.PlayerRankModule;
import yxy.game.pm2.bean.module.rank.RankEntry;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.bean.pubsub.ArenaRankPublisher;
import yxy.game.pm2.bean.task.TaskType;
import yxy.game.pm2.module.mail.MailHandle;
import yxy.game.pm2.module.mail.MailTypeEnum;
import yxy.game.pm2.module.task.TaskHandle;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

public class RankArena extends PlayerRankModule {
	private static final Logger logger = Logger.create(RankArena.class);

	public RankArena(AreaBean areaBean) {
		super(areaBean);
	}

	@Override
	public String rankName() {
		return PlayerRankModule.getAllRankNames().get(0);
	}

	@Override
	protected long valuePlastic(long value) {
		return value * 1000;
	}

	@Override
	protected long valueRestore(long score) {
		return score / 1000;
	}

	@Override
	public RankEntry get(String key) {
		try {
			if (tryLock()) {
				RankEntry entry = super.get(key);
				return entry;
			}
		} catch (Exception e) {
		} finally {
			unlock();
		}
		return null;
	}

	@Override
	public void handleUpdate(DateTime ori, DateTime now) {
		if (new LocalDate(now).equals(new LocalDate(ori))) {
			return;
		}
		//是否同一周
		boolean weekUpdate = new LocalDate(now).getWeekOfWeekyear() != new LocalDate(ori).getWeekOfWeekyear();
//		boolean weekUpdate = true;

		// 不是同一天，发日结算奖励
		ArrayList<RankEntry> dailyTop = dailyTop();
		rewardDayRank(dailyTop);

		//不是同一周，发周奖励
		ArrayList<RankEntry> weekyTop = null;
		if (weekUpdate) {
			weekyTop = weekyTop();
			resetRank();
			rewardWeekRank(weekyTop);
		}

//		ThreadPoolManager.getInstance().execute(new Runnable() {
//
//			@Override
//			public void run() {
//				ArrayList<RankEntry> dailyTop = dailyTop();
//				rewardDayRank(dailyTop);
//				ArrayList<RankEntry> weekyTop = null;
//				if (weekUpdate) {
//					weekyTop = weekyTop();
//					resetRank();
//					rewardWeekRank(weekyTop);
//				}
//
//			}
//		});

	}

	private ArrayList<RankEntry> dailyTop() {
		int min = -1;// 全局最小
		int max = -1;// 全局最大
		Map<String, arenasignreward> all = DataCenter.getAllData(arenasignreward.class);
		for (arenasignreward data : all.values()) {
			if (min < 0 || data.getRankingmin() < min) {
				min = data.getRankingmin();
			}
			if (max < 0 || data.getRankingmax() > max) {
				max = data.getRankingmax();
			}
		}
		return new ArrayList<>(range(min, max));
	}

	private ArrayList<RankEntry> weekyTop() {
		int min = -1;// 全局最小
		int max = -1;// 全局最大
		Map<String, arenarankreward> all = DataCenter.getAllData(arenarankreward.class);
		for (arenarankreward data : all.values()) {
			if (min < 0 || data.getRankingmin() < min) {
				min = data.getRankingmin();
			}
			if (max < 0 || data.getRankingmax() > max) {
				max = data.getRankingmax();
			}
		}
		return new ArrayList<>(range(min, max));
	}

	//日奖励发放
	private void rewardDayRank(ArrayList<RankEntry> dailyTop) {
		AreaBean areaBean = AreaBean.get(getAreaId());
		if (areaBean.isMeraged()) return;

		logger.info("区服%s::竞技场发日常排名奖励了！！！！", getAreaId());
		Map<String, arenasignreward> all = DataCenter.getAllData(arenasignreward.class);
		for (arenasignreward data : all.values()) {
			Collection<Currency> rewards = Currency.create(data.getRewardtype(), data.getRewardid(), data.getRewardnum());

			for (int i = data.getRankingmin() - 1; i < data.getRankingmax() && i < dailyTop.size(); i++) {
				int rank = i + 1;
				RankEntry entry = dailyTop.get(i);
				String title = GameString.竞技场日常奖励_title(rank).getText();
				String content = GameString.竞技场日常奖励_msg(rank).getText();
				new MailHandle().sendMail(entry.getKey(), MailTypeEnum.Mail, title, content, CCReason.竞技场, rewards);

				// 结算成就
				TaskHandle.handle(entry.getKey(), TaskType.指标型_擂台_名次_达到, -rank);
			}
		}
		logger.info("区服%s::竞技场日常排名奖励发完了", getAreaId());
	}

	//周奖励发放
	private void rewardWeekRank(ArrayList<RankEntry> weekyTop) {
		AreaBean areaBean = AreaBean.get(getAreaId());
		if (areaBean.isMeraged()) return;

		logger.info("区服%s::竞技场发赛季排名奖励了！！！！", getAreaId());
		Map<String, arenarankreward> all = DataCenter.getAllData(arenarankreward.class);
		for (arenarankreward data : all.values()) {
			Collection<Currency> rewards = Currency.create(data.getRewardtype(), data.getRewardid(), data.getRewardnum());

			for (int i = data.getRankingmin() - 1; i < data.getRankingmax() && i < weekyTop.size(); i++) {
				int rank = i + 1;
				RankEntry entry = weekyTop.get(i);
				String title = GameString.竞技场排名奖励_title(rank).getText();
				String content = GameString.竞技场排名奖励_msg(rank).getText();
				new MailHandle().sendMail(entry.getKey(), MailTypeEnum.Mail, title, content, CCReason.竞技场, rewards);

				ArenaRankPublisher.getInstance().publish(entry.getKey(), rank);
			}
		}
		logger.info("区服%s::竞技场赛季排名奖励发完了", getAreaId());
	}

	private void resetRank() {
		try {
			if (tryLock()) {
				AreaBean areaBean = AreaBean.get(getAreaId());
				logger.info("区服%s::竞技场开始清分", getAreaId());
				ArrayList<RankEntry> top = new ArrayList<>(range(1, topSize()));
				touch().clear();

				if (!areaBean.isMeraged()) { //被合并过的区不再有排行榜
					int initScore = fomula.竞技场初始分数.intValue();
					for (RankEntry entry : top) {
						String key = entry.getKey();
						addScore(key, initScore);
					}
				}
				logger.info("区服%s::竞技场清分结束", getAreaId());
			}
		} catch (Exception e) {
		} finally {
			unlock();
		}
	}

	static public void reset() {
		redis().client().getKeys().deleteByPattern("AREA:*:RANK:ARENA");

		Collection<PlayerBean> all = PlayerBean.all();
		int initScore = fomula.竞技场初始分数.intValue();
		for (PlayerBean bean : all) {
			if (bean.getPower() <= 0) {
				continue;
			}
			String pCode = bean.getCode();
			AreaBean areaBean = AreaModule.area(bean);
			ArenaPlayerModule module = ArenaPlayerModule.get(pCode);
			if (module != null) {
				new RankArena(areaBean).put(pCode, initScore);
			}
		}
	}

	static public RankArena getRank(String playerCode) {
		AreaBean areaBean = AreaModule.area(playerCode);
		return new RankArena(areaBean);
	}
}
